package com.ficus.road.maintain.third.dk;

import cn.hutool.http.HttpStatus;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ficus.road.maintain.core.model.xlj.Xlj;
import com.ficus.road.maintain.core.model.zh.xlj.XljBasicInfoZH;
import com.ficus.road.maintain.dao.xlj.XljCameraGroupDao;
import com.ficus.road.maintain.dao.xlj.XljDao;
import com.ficus.road.maintain.service.XljService;
import com.google.common.base.Objects;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @author xiawen yang
 * @date 2022/7/8 下午3:14
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class DKCameraInfo extends BaseDK {

    private static final String REQ_TYPE = "get_camera_request";
    private final XljService xljService;
    private final XljDao xljDao;
    private final XljCameraGroupDao xljCameraGroupDao;

    @Scheduled(cron = "0 0 12,14,16 * * ?")
//    @Scheduled(cron = "0/5 * * * * ?")
    public void refreshCameraInfo() {
        Date now = new Date();
        Optional<DKCameraHttpResponse> optional = getDKData(DKCameraHttpResponse.class);
        if (optional.isEmpty() || Objects.equal(optional.get().getRetHeader().getCode(), HttpStatus.HTTP_INTERNAL_ERROR)) {
            return;
        }

        // 清理下立交摄像头列表
//        xljService.clearXljCameraList();

        AtomicInteger atomicInteger = new AtomicInteger();

        Map<Integer, List<XljCameraInfo>> cameraGroup = optional.get().getRetBody().getCameraList().stream().collect(Collectors.groupingBy(XljCameraInfo::getGroupId));
        cameraGroup.forEach((groupId, groupInfo) -> {
            DkCameraGroup.XljCameraGroup fetch = xljCameraGroupDao.fetch(groupId);
            if (ObjectUtils.isEmpty(fetch)) {
                log.info("groupId: {} cannot be found in CameraGroup", groupId);
                return;
            }
            Xlj xlj = xljDao.findOne(new Query(Criteria.where("xlj_name").is(transferXljName(fetch.getGroupName()))));
            if (ObjectUtils.isEmpty(xlj)) {
                log.info("groupName: {} cannot be found in xljInfo", fetch.getGroupName());
                return;
            }
            List<XljBasicInfoZH.Camera> cameraList = groupInfo.stream().map(item -> XljBasicInfoZH.Camera.builder()
                    .cameraId(item.getId() + "")
                    .cameraName(item.getName())
                    .updateTime(now).build()).collect(Collectors.toList());
            if (ObjectUtils.isNotEmpty(cameraList)) {
                atomicInteger.incrementAndGet();
            }
            xlj.setCameras(cameraList);
            xljDao.saveOrUpdate(xlj);
        });
        log.info("下立交摄像头更新完成, 电科总数: {}, 更新到系统的个数: {}", cameraGroup.size(), atomicInteger.get());
    }

    @Override
    protected String getReqType() {
        return REQ_TYPE;
    }

    public String transferXljName(String xljName) {
        String suffix = "（已封闭）";
        if (xljName.contains(suffix)) {
            xljName = StringUtils.substringBefore(xljName, suffix);
        }
        return xljName.replace("（", "(").replace("）", ")");
    }

    @Data
    public static class DKCameraHttpResponse extends DKBasicHttpResponse {
        @JsonProperty("ret_body")
        private CameraReqBody retBody;
    }

    @Data
    public static class XljCameraInfo {
        @JsonProperty("group_id")
        private int groupId;

        private String name;

        private int id;
        @JsonProperty("ptz_able")
        private int ptzAble;
    }

    @Data
    public static class CameraReqBody {
        @JsonProperty("camera_list")
        private List<XljCameraInfo> cameraList;
    }
}
